package sqlToGUI.charts;


import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Paint;

import javax.swing.ImageIcon;

import org.jfree.chart.ChartFactory;
//import org.jfree.chart.ChartFrame;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.axis.ValueAxis;
//import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

import sqlToGUI.charts.helperUtilities.TelemetryChartEvent;
import sqlToGUI.charts.helperUtilities.TelemetryChartListener;
import sqlToGUI.charts.helperUtilities.TelemetryDataEntry;


public class ArrayCurrent implements GUIDisplay {
	
	private int y = 1;
	
	/**The list receiving the new data from the outside -
	 * This class will be responsible for listening to this
	 * list and updating from it whenever new information
	 * is available -
	 * The array is used in case chart uses reference to more
	 * than one data set and is updated from more than one
	 * list */
	private TelemetryDataEntry [] dataEntries;
	
	/**Tells whether or not a chart has been loaded */
	private boolean chartLoaded;
	/**Tells whether or not data has been initialized */
	private boolean dataEntrySet;
	
	/**JFreeChart object that we're drawing */
	private JFreeChart chart;
	
	/**The object returned containing the chart */
	private ChartPanel chartContainer;
	
	private ValueAxis axis;
	private ValueAxis range;
	
	/**The log panel data will monitor the incoming data */
	private LogPanel log;
	/**Variable indicating whether or not a log has been
	 * registered */
	private boolean logReg = false;
	
	/**ChartFrame, an extension of JFrame */
	//private ChartFrame cf;
	
	/**The original position of the labels, we need this to reset 
	 * the labels to 0 degree rotation */
	CategoryLabelPositions originalLabelPosition;
	
	/**Plot stuff....no idea */
	//private CategoryPlot plot;

	/**The data field that specifies the width of the ChartFrame window */
	//private JTextField widthField;
	
	/**The data field that specifies the height of the ChartFrame 
	 * window */
	//private JTextField heightField;
	
	/**The data field that specifies the amount of rotation of the text 
	 * labels */
	//private JTextField rotateField;
	
	/**rotation of the text label, set to 45 by default (defect was reproduced
	  *with this value) */
	//private double rotation = 45.0;
	
	/**
	 * draw the chart as specified in CR
	 * Not much to explain, just draws some bar chart with some data
	 */
	private XYSeries s1;
	private XYSeries s2;
	private XYSeriesCollection dataset;
	
	public ArrayCurrent(){
		makeChart();
	}
	
	/**Register the given log so that it can monitor incoming data */
	public GUIDisplay registerLog(LogPanel log){
		this.log = log;
		logReg = true;
		return this;
	}
	
	/**Create the display chart */
	private void makeChart() {
		
		dataset = new XYSeriesCollection();
		s1 = new XYSeries("Series 1");
		s2 = new XYSeries("Series 2");

        dataset.addSeries(s1);
        dataset.addSeries(s2);
		
		chart = ChartFactory.createXYLineChart(
            "Array Current",         // chart title
            "Time (milli-seconds)",  // domain axis label
            "Array Current (Amps)",     // range axis label
            dataset,                  // data
            PlotOrientation.VERTICAL,
            true,                     // include legend
            true,
            false
        );
		
		chart.setBackgroundPaint(new GradientPaint(0,0, Color.CYAN, 0, 1000, Color.BLUE));
		chart.setBorderPaint(new GradientPaint(0,0, Color.CYAN, 0, 1000, Color.BLUE));
		
		final ImageIcon n = new ImageIcon("backgrounds/background2.jpg");
		XYPlot plot = chart.getXYPlot();
		
		plot.setBackgroundImage(n.getImage());
		plot.setBackgroundImageAlpha(0.1f);
		
		plot.getRenderer().setSeriesPaint(0, new Color(0x3D057A));
		
		plot.setOutlinePaint(Color.YELLOW);
		plot.getDomainAxis().setLabelPaint(new Color(0x236535));
		
		plot.getRangeAxis().setLabelPaint(new Color(0x80633C));
		
		Font t = new Font(Font.MONOSPACED, Font.PLAIN, 14);
		plot.getDomainAxis().setLabelFont(t);
		
		chartLoaded = true;
		dataEntrySet = true;
		
		axis = plot.getDomainAxis();
		range = plot.getRangeAxis();
		
		axis.setAutoRange(false);
		range.setAutoRange(true);

		chartContainer = new ChartPanel(new JFreeChart(plot));

		/*
		for(int i = 0; i < 500; i++) {
			try {
				Thread.sleep(1);
			} catch (Exception e) {}
			try {
				s1.add(i+50, Math.sin(i), true);
				s2.add(i+50, Math.cos(i)+ 5, true);
				axis.setRange(i+1,i+51);
			} catch (Exception e) {
				System.out.println(e.getMessage());
				e.printStackTrace();
			}
		}
		*/
		
		//list.addActionListener(dataEntry);
	
	}
	
	/**Moved the frame for which the data will be displayed on the chart */
	public void addToBuffer(int index, double value){
		
	}
	
	/**Returns the chart that plots the data */
	public ChartPanel getChart(){
		while(!chartLoaded){
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		return chartContainer;
	}
	
	/**Return the buffer for the chart */
	public TelemetryDataEntry [] getBuffers() {
		
		while(!dataEntrySet){
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
		dataEntries = new TelemetryDataEntry [2];
		for(int i = 0; i < dataEntries.length; i++)
			dataEntries[i] = new TelemetryDataEntry(1);
			
		/**Create the event(update chart) when this buffer receives
		 * new data */
		dataEntries[0].addTelemetryChartEventListener(
				new TelemetryChartListener() {
			public void myEventOccurred(TelemetryChartEvent evt) {
				s1.add(1000*y, dataEntries[0].getUpdate()[0]);
				axis.setRange(1000*(y-18),1000*y);
				y++;
			}
		});
		dataEntries[1].addTelemetryChartEventListener(
				new TelemetryChartListener() {
			public void myEventOccurred(TelemetryChartEvent evt) {
				s2.add(1000*y, dataEntries[1].getUpdate()[0]);
				y++;
			}
		});

		/**TODO: send data to the log*/
		
		return dataEntries;
	}
}
